package com.tqfframe.studydemo.myDubboRpc.core.handler;

import com.alibaba.fastjson.JSON;
import com.tqfframe.studydemo.myDubboRpc.core.entiy.PorxyEntity;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;

/**
 * Created by Tang-QiFeng on 2022/2/18
 */
@Sharable
public class ServerHandler extends ChannelInboundHandlerAdapter {

    private Logger logger=LoggerFactory.getLogger(this.getClass());

    private String rpc_interface;

    public ServerHandler(String rpc_interface) {
        this.rpc_interface = rpc_interface;
    }

    /**
     * 接收客户端传送过来的参数，做处理后，使用writeAndFlush方法再传送到客户端
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        PorxyEntity porxyEntity = JSON.parseObject(msg.toString(),PorxyEntity.class);

        //从注册表中获取服务的字节码
        Class aClass =Class.forName(rpc_interface);
        logger.info(porxyEntity.getName());
        logger.info(porxyEntity.getMethod());
        //通过字节码对象获取构造器
        Constructor constructor=aClass.getConstructor();
        //通过反射的方式创建对象并且执行对象的方法
        Object invoke = aClass.getMethod(porxyEntity.getMethod(),porxyEntity.getParameterTypes()).invoke(constructor.newInstance(), porxyEntity.getArgs());
        if(invoke!=null){
            logger.info(invoke.toString());
            ctx.writeAndFlush(invoke.toString());
        }else{
            ctx.writeAndFlush("void方法也必须要传输一个参数过去，否则客户端那边的连接会阻塞");
        }
    }

    //读取完成后处理方法 ，也就是channelRead执行完后再执行的方法
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        System.out.println("执行完channelRead方法了。");
        //ctx.flush();
    }


    //客户端服务第一次连接后执行
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("当前链路已经激活了，有客户端与服务端建立连接");
        ctx.fireChannelActive();
    }

    //客户端服务断开连接后执行
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端链接断开了，可能是客户端宕机。。。");
        ctx.fireChannelInactive();
    }

    //异常捕获处理方法
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        cause.printStackTrace();
        ctx.close();
    }

}
